﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VastPark.FrameworkBase.ComponentModel;
using System.Xml.Linq;

namespace ImmlPad.UpdateManagement
{
    public class CheckForUpdateTask : VastPark.FrameworkBase.TaskEvent
    {
        public event Event<ReleaseInfo> NewVersionAvailable;

        /// <summary>
        /// The version that is being returned as the newest available version of ImmlPad
        /// </summary>
        public Version NewestVersion { get; private set; }

        /// <summary>
        /// The URI the newest version can be downloaded from
        /// </summary>
        public string DownloadUri { get; private set; }

        /// <summary>
        /// The release date of the CurrentVersion
        /// </summary>
        public DateTime ReleaseDate { get; private set; }

        private const string UPDATE_URI = "http://immlpad.codeplex.com/wikipage?title=CurrentVersion";
        private Version _Version;

        public CheckForUpdateTask(Version version)
            : base(null)
        {
            _Version = version;
        }

        private const string VERSION_START = "&lt;Version&gt;";
        private const string VERSION_END = "&lt;/Version&gt;";

        private const string RELEASE_DATE_START = "&lt;ReleaseDate&gt;";
        private const string RELEASE_DATE_END = "&lt;/ReleaseDate&gt;";

        private const string DOWNLOAD_URI_START = "&lt;DownloadLink&gt;";
        private const string DOWNLOAD_URI_END = "&lt;/DownloadLink&gt;";

        public override void Update(float timeDelta)
        {
            try
            {
                var request = VastPark.FrameworkBase.Net.Web.CreateRequest(UPDATE_URI);
                var response = VastPark.FrameworkBase.Net.Web.PerformRequest(request, null);

                if (!string.IsNullOrEmpty(response))
                {
                    //trim the response to the area of interest
                    var startIndex = response.IndexOf(VERSION_START);
                    response = response.Substring(startIndex, response.IndexOf(DOWNLOAD_URI_END, startIndex) - startIndex + DOWNLOAD_URI_END.Length);

                    //expected response format:
                    //<Version>versionNo</Version>
                    //<ReleaseDate>date</ReleaseDate>
                    //<DownloadLink>uri</DownloadLink>

                    var split = response.Split(new string[] { "<br/>", "<br />" }, StringSplitOptions.RemoveEmptyEntries);

                    if (split.Length == 3)
                    {
                        var version = split[0].Replace(VERSION_START, string.Empty).Replace(VERSION_END, string.Empty);
                        this.NewestVersion = new Version(version);

                        if (this.NewestVersion > _Version) //only bother with the rest if the version is newer
                        {
                            var date = split[1].Replace(RELEASE_DATE_START, string.Empty).Replace(RELEASE_DATE_END, string.Empty);
                            var dateTime = DateTime.MinValue;

                            if (DateTime.TryParse(date, out dateTime))
                            {
                                this.ReleaseDate = dateTime;
                            }

                            this.DownloadUri = split[2].Replace(DOWNLOAD_URI_START, string.Empty).Replace(DOWNLOAD_URI_END, string.Empty);
                            this.NewVersionAvailable.Raise(this, new ReleaseInfo { DownloadUri = this.DownloadUri, ReleaseDate = this.ReleaseDate, Version = this.NewestVersion, ChangeLog = "N/A" });
                        }
                    }
                }
            }
            catch { } //eat the exception, update notification isn't critical
            
            this.IsComplete = true;
        }
    }
}
